// @ts-check

// 如果尝试表示计算任意数 n 的阶乘的步骤，可以将步骤定义如下：(n) * (n - 1) * (n - 2) * (n - 3) * ... * 1。
// 可以使用循环来写一个计算一个数阶乘的函数，如下所示。
function factorialIterative(number) {
  if (number <= 0) return undefined;
  let total = 1;
  for (let n = number; n > 1; n--) {
    total = total * n;
  }
  return total;
}

console.log('factorialIterative(5): ', factorialIterative(5));
console.log('factorialIterative(3): ', factorialIterative(3));

// 用递归来重写 factorialIterative 函数，但是首先使用递归的定义来定义所有的步骤。
/**
 * 5 的阶乘用 5 × 4 × 3 × 2 × 1 来计算。
 * 4(n - 1)的阶乘用 4 × 3 × 2 × 1 来计算。
 * 计算 n - 1 的阶乘是我们计算原始问题 n!的一个子问题，因此可以像下面这样定义 5 的阶乘。
 * (1) factorial(5) = 5 * factorial(4)：我们可以用 5 × 4!来计算 5!。
 * (2) factorial(5) = 5 * (4 * factorial(3))：我们需要计算子问题 4!，它可以用 4 × 3!来计算。
 * (3) factorial(5) = 5 * 4 * (3 * factorial(2))：我们需要计算子问题 3!，它可以用 3 × 2!来计算。
 * (4) factorial(5) = 5 * 4 * 3 * (2 * factorial(1))：我们需要计算子问题 2!，它可以用 2 × 1!来计算。
 * (5) factorial(5) = 5 * 4 * 3 * 2 * (1)：我们需要计算子问题 1!。
 * (6) factorial(1)或 factorial(0)返回 1。1!等于 1。我们也可以说 1! = 1 × 0!，0!也等于 1。
 */

/**
 * factorial函数本身是为了完成阶乘
 */
function factorial(n) {
  if (n === 1 || n === 0) {
    return 1;
  }
  return n * factorial(n - 1);
}
console.log('factorial(5): ', factorial(5));
console.log('factorial(3): ', factorial(3));

